package com.android.widget;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.FrameLayout;
import android.widget.ScrollView;

import com.android.R;
import com.android.view.SwipeRequestView;

/**
 * Created by Relin
 * on 2018-09-26.
 */
public class SwipeRequestLayout extends FrameLayout {

    //头部视图
    private SwipeRequestView headerView;
    //内容视图
    private View contentView[];
    //底部视图
    private SwipeRequestView footerView;
    //头部高度
    private float headerHeight = dpToPx(80);
    //脚部高度
    private float footerHeight = dpToPx(80);
    //刷新是否可用
    private boolean refreshEnable = true;
    //加载是否可用
    private boolean loadEnable = false;
    //是否超限距离
    private boolean isTransfinite = false;
    //是否正在刷新
    private boolean isRefreshing = false;
    private boolean isRefreshingRelease = false;
    //是否正在加载
    private boolean isLoading = false;
    private boolean isLoadingRelease = false;
    //按下的坐标
    private float downX, downY;
    //刷新移动距离
    private float refreshMoveY = 0;
    //加载移动距离
    private float loadMoveY = 0;
    //刷新停留距离
    private float refreshRemainY = 0;
    //加载停留距离
    private float loadRemainY = 0;
    //刷新监听
    private OnSwipeRefreshListener refreshListener;
    //加载监听
    private OnSwipeLoadListener loadListener;
    //缩放动画师
    private ValueAnimator animator;
    //缩放时间
    private int scaleDuration = 500;
    //延迟时间
    private int delayDuration = 200;
    //头部阴影
    private int headerShadowColor;
    //脚部阴影
    private int footerShadowColor;
    //内容类型-列表
    private AbsListView absListView;
    //内容类型-ScrollView
    private ScrollView scrollView;

    public SwipeRequestLayout(@NonNull Context context) {
        super(context);
        initHeaderFooter(context, null);
    }

    public SwipeRequestLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initHeaderFooter(context, attrs);
    }

    public SwipeRequestLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initHeaderFooter(context, attrs);
    }

    /**
     * 初始话头部和底部View
     *
     * @param context
     */
    private void initHeaderFooter(Context context, AttributeSet attrs) {
        headerView = new SwipeRequestView(context);
        footerView = new SwipeRequestView(context);
        headerShadowColor = headerView.getShadowColor();
        footerShadowColor = footerView.getShadowColor();
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SwipeRequestLayout);
        headerHeight = typedArray.getDimension(R.styleable.SwipeRequestLayout_headerHeight, headerHeight);
        footerHeight = typedArray.getDimension(R.styleable.SwipeRequestLayout_footerHeight, footerHeight);
        refreshEnable = typedArray.getBoolean(R.styleable.SwipeRequestLayout_refreshEnable, refreshEnable);
        loadEnable = typedArray.getBoolean(R.styleable.SwipeRequestLayout_loadEnable, loadEnable);
        scaleDuration = typedArray.getInt(R.styleable.SwipeRequestLayout_scaleDuration, scaleDuration);
        delayDuration = typedArray.getInt(R.styleable.SwipeRequestLayout_delayDuration, delayDuration);
        headerShadowColor = footerShadowColor = typedArray.getColor(R.styleable.SwipeRequestLayout_shadowColor, headerShadowColor);
        Log.e("RRL", "refreshEnable:" + refreshEnable + ",loadEnable:" + loadEnable);
        typedArray.recycle();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //内容
        contentView = new View[getChildCount()];
        for (int i = 0; i < getChildCount(); i++) {
            if (getChildAt(i) instanceof ScrollView) {
                scrollView = (ScrollView) getChildAt(i);
                //解决不是顶部问题
                setFocusable(true);
                setFocusableInTouchMode(true);
            }
            if (getChildAt(i) instanceof AbsListView) {
                absListView = (AbsListView) getChildAt(i);
            }
            contentView[i] = getChildAt(i);
        }
        //头部
        LayoutParams headerParams = new LayoutParams(LayoutParams.MATCH_PARENT, (int) headerHeight);
        headerView.setLayoutParams(headerParams);
        headerView.setBackgroundColor(Color.TRANSPARENT);
        addView(headerView);
        //脚部
        LayoutParams footerParams = new LayoutParams(LayoutParams.MATCH_PARENT, (int) footerHeight);
        footerView.setLayoutParams(footerParams);
        footerView.setBackgroundColor(Color.TRANSPARENT);
        footerParams.gravity = Gravity.BOTTOM;
        addView(footerView);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        //头部
        MarginLayoutParams headerParams = (MarginLayoutParams) headerView.getLayoutParams();
        left = getPaddingLeft() + headerParams.leftMargin;
        top = getPaddingTop() + headerParams.topMargin - headerView.getMeasuredHeight() + (int) refreshRemainY + (int) refreshMoveY;
        right = left + headerView.getMeasuredWidth();
        bottom = top + headerView.getMeasuredHeight();
        headerView.layout(left, top, right, bottom);
        //内容区域
        for (int i = 0; i < contentView.length; i++) {
            View child = contentView[i];
            MarginLayoutParams childParams = (MarginLayoutParams) child.getLayoutParams();
            left = getPaddingLeft() + childParams.leftMargin;
            top = getPaddingTop() + childParams.topMargin;
            right = left + child.getMeasuredWidth();
            bottom = top + child.getMeasuredHeight();
            child.layout(left, top, right, bottom);
        }
        //脚部
        MarginLayoutParams footerParams = (MarginLayoutParams) footerView.getLayoutParams();
        left = getPaddingLeft() + footerParams.leftMargin;
        top = getMeasuredHeight() + getPaddingTop() + footerParams.topMargin + (int) loadRemainY + (int) loadMoveY;
        right = left + footerView.getMeasuredWidth();
        bottom = top + footerView.getMeasuredHeight();
        footerView.layout(left, top, right, bottom);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveY = event.getY() - downY;
                float moveX = event.getX() - downX;
                if (Math.abs(moveY) < moveX) {
                    return super.onInterceptTouchEvent(event);
                }
                if (moveY > 0 && refreshEnable) {
                    return isContentViewRefreshEnable();
                }
                if (moveY < 0 && loadEnable) {
                    return isContentViewLoadEnable();
                }
                break;
        }
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
                if (isRefreshingRelease) {
                    headerView.start();
                    headerView.setShadowColor(headerShadowColor);
                    if (refreshListener != null && refreshMoveY > 0 && refreshEnable && isTransfinite) {
                        refreshListener.onSwipeRefresh();
                    }
                    if (isTransfinite) {
                        isRefreshing = true;
                        refreshRemainY = headerHeight;
                        refreshMoveY = 0;
                        requestLayout();
                    } else {
                        createScaleAnimator(headerView).start();
                    }
                    return true;
                }
                if (isLoadingRelease) {
                    footerView.start();
                    footerView.setShadowColor(footerShadowColor);
                    loadRemainY = loadEnable ? -footerView.getMeasuredHeight() : 0;
                    if (loadListener != null && loadMoveY < 0 && loadEnable && isTransfinite) {
                        loadListener.onSwipeLoad();
                    }
                    if (isTransfinite) {
                        isLoading = true;
                        refreshRemainY = -headerHeight;
                        loadMoveY = 0;
                        requestLayout();
                    } else {
                        createScaleAnimator(footerView).start();
                    }
                    return true;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (isLoading || isRefreshing) {
                    break;
                }
                float moveY = event.getY() - downY;
                moveY *= 0.25F;
                //利用屏幕的1/5做界限
                int each = 8;
                float movePercent = (moveY) / (getMeasuredHeight() / each);
                isTransfinite = Math.abs(movePercent) > 1;
                if (Math.abs(movePercent) > each) {
                    break;
                }
                if (moveY > 0 && refreshEnable && !isLoading) {//下滑
                    headerView.setScaleX(1);
                    headerView.setScaleY(1);
                    headerView.cancel();
                    headerView.setArcStartAngle(-90);
                    headerView.setArcSweepAngle(360 * movePercent);
                    headerView.setShadowColor(refreshEnable ? headerView.getArcColor() : headerShadowColor);
                    refreshMoveY = moveY;
                    isRefreshingRelease = true;
                    isLoadingRelease = false;
                }
                if (moveY < 0 && loadEnable && !isRefreshing) {//上滑
                    footerView.setScaleX(1);
                    footerView.setScaleY(1);
                    footerView.cancel();
                    footerView.setArcStartAngle(-90);
                    footerView.setArcSweepAngle(360 * Math.abs(movePercent));
                    footerView.setShadowColor(loadEnable ? footerView.getArcColor() : footerShadowColor);
                    loadMoveY = moveY;
                    isRefreshingRelease = false;
                    isLoadingRelease = true;
                }
                if (isRefreshingRelease || isLoadingRelease) {
                    requestLayout();
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (animator != null) {
            animator.removeAllUpdateListeners();
            animator.cancel();
            animator = null;
        }
    }

    public float dpToPx(float dp) {
        return dp * getScreenDensity();
    }

    public float getScreenDensity() {
        return Resources.getSystem().getDisplayMetrics().density;
    }

    public interface OnSwipeRefreshListener {
        void onSwipeRefresh();
    }

    /**
     * 设置刷新监听
     *
     * @param refreshListener
     */
    public void setOnSwipeRefreshListener(OnSwipeRefreshListener refreshListener) {
        this.refreshListener = refreshListener;
        if (isRefreshing) {
            setRefreshing(isRefreshing);
        }
    }

    public interface OnSwipeLoadListener {
        void onSwipeLoad();
    }

    /**
     * 设置加载监听
     *
     * @param loadListener
     */
    public void setOnSwipeLoadListener(OnSwipeLoadListener loadListener) {
        this.loadListener = loadListener;
        if (isLoading) {
            setLoading(isLoading);
        }
    }

    /**
     * 设置正在刷新
     *
     * @param isRefreshing 是否开始刷新
     */
    public void setRefreshing(boolean isRefreshing) {
        if (!isRefreshing) {
            if (!this.isRefreshing) {
                return;
            }
            createScaleAnimator(headerView).start();
        } else {
            if (!refreshEnable) {
                return;
            }
            refreshRemainY = headerHeight;
            headerView.start();
            if (refreshListener != null) {
                refreshListener.onSwipeRefresh();
            }
        }
        this.isRefreshing = isRefreshing;
    }

    /**
     * 设置正在加载
     *
     * @param isLoading 是否开始加载
     */
    public void setLoading(boolean isLoading) {
        if (!isLoading) {
            if (!this.isLoading) {
                return;
            }
            createScaleAnimator(footerView).start();
        } else {
            if (!loadEnable) {
                return;
            }
            footerView.start();
            loadRemainY = -footerHeight;
            if (loadListener != null) {
                loadListener.onSwipeLoad();
            }
        }
        this.isLoading = isLoading;
    }

    /**
     * 创建缩放动画师
     *
     * @param view 控件
     * @return 动画师
     */
    private synchronized ValueAnimator createScaleAnimator(final View view) {
        if (animator != null && animator.isStarted() && animator.isRunning()) {
            animator.removeAllUpdateListeners();
            animator = null;
        }
        animator = ValueAnimator.ofFloat(1, 0);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                view.setScaleX(value);
                view.setScaleY(value);
            }
        });
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                refreshRemainY = 0;
                loadRemainY = 0;
                refreshMoveY = 0;
                loadMoveY = 0;
                requestLayout();
                isRefreshing = false;
                isLoading = false;
                isTransfinite = false;
                headerView.cancel();
                footerView.cancel();
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.setStartDelay(refreshEnable ? delayDuration : 0);
        animator.setDuration(scaleDuration);
        return animator;
    }

    /**
     * 内容去是否可以刷新
     *
     * @return
     */
    private boolean isContentViewRefreshEnable() {
        if (scrollView != null && scrollView.getScrollY() > 0) {
            return false;
        }
        if (absListView != null && absListView.getFirstVisiblePosition() > 0) {
            return false;
        }
        return true;
    }

    /**
     * 内容区域是否可以加载
     *
     * @return
     */
    private boolean isContentViewLoadEnable() {
        if (scrollView != null && scrollView.getChildAt(0).getMeasuredHeight() > scrollView.getScrollY() + scrollView.getHeight()) {
            return false;
        }
        if (absListView != null && absListView.getLastVisiblePosition() < (absListView.getCount() - 1)) {
            return false;
        }
        return true;
    }

    public void setHeaderHeight(float headerHeight) {
        this.headerHeight = headerHeight;
    }

    public void setFooterHeight(float footerHeight) {
        this.footerHeight = footerHeight;
    }

    public void setRefreshEnable(boolean refreshEnable) {
        this.refreshEnable = refreshEnable;
    }

    public void setLoadEnable(boolean loadEnable) {
        this.loadEnable = loadEnable;
    }

    public void setScaleDuration(int scaleDuration) {
        this.scaleDuration = scaleDuration;
    }

    public void setDelayDuration(int delayDuration) {
        this.delayDuration = delayDuration;
    }

    public void setHeaderShadowColor(int headerShadowColor) {
        this.headerShadowColor = headerShadowColor;
    }

    public void setFooterShadowColor(int footerShadowColor) {
        this.footerShadowColor = footerShadowColor;
    }
}
